#include<iostream>
using namespace std;
class term
{
public:
	int col;
	int rank;
	int value;
};
class matrix
{
public:
	int col;
	int rank;
	term* theterm;
	int size;
	int* COL;
	int* RANK;
	void input1();
	void input2();
	void output1();
	void output2();
	void trans();
};
void matrix::input1()
{
	cin >> rank;
	cin >> col;
	theterm = new term[rank * col];
	RANK = new int[rank + 1];
	COL = new int[col + 1];
	for (int i = 1; i <= rank; i++)
	{
		RANK[i] = 0;
	}
	for (int i = 1; i <= col; i++)
	{
		COL[i] = 0;
	}
	int no = 0;
	int n;
	for (int i = 0; i < rank * col; i++)
	{
		cin >> n;
		if (n != 0)
		{
			theterm[no].value = n;
			theterm[no].rank = i / col + 1;
			theterm[no].col = i % col + 1;
			COL[i % col + 1]++;
			RANK[i / col + 1]++;
			no++;
		}
	}
	size = no;
}

void matrix::input2()
{
	cin >> rank;
	cin >> col;
	cin >> size;
	theterm = new term[size];
	RANK = new int[rank + 1];
	COL = new int[col + 1];
	for (int i = 1; i <= rank; i++)
	{
		RANK[i] = 0;
	}
	for (int i = 1; i <= col; i++)
	{
		COL[i] = 0;
	}
	for (int i = 0; i < size; i++)
	{
		cin >> theterm[i].rank;
		RANK[theterm[i].rank]++;
		cin >> theterm[i].col;
		COL[theterm[i].col]++;
		cin >> theterm[i].value;
	}

}

void matrix::output1()
{
	cout << rank << " " << col << endl;
	int n = 0;
	for (int i = 1; i <= rank; i++)
	{
		for (int j = 1; j <= col; j++)
		{
			if (theterm[n].rank == i && theterm[n].col == j)
			{
				cout << theterm[n].value << ' ';
				n++;
			}
			else
			{
				cout << 0 << ' ';
			}
		}
		cout << endl;
	}

}

void matrix::output2()
{
	for (int i = 0; i < size; i++)
	{
		cout << theterm[i].rank << ' ' << theterm[i].col << ' ' << theterm[i].value << endl;
	}


}

void matrix::trans()
{
	int* media = new int[col + 1];
	media[1] = 0;
	for (int i = 2; i <= col; i++)
	{
		media[i] = media[i - 1] + COL[i - 1];
	}
	int n = col;
	col = rank;
	rank = n;
	int* m = COL;
	COL = RANK;
	RANK = m;
	term* newterm = new term[size];
	for (int i = 0; i < size; i++)
	{
		newterm[media[theterm[i].col]].value = theterm[i].value;
		newterm[media[theterm[i].col]].rank = theterm[i].col;
		newterm[media[theterm[i].col]].col = theterm[i].rank;
		media[theterm[i].col]++;
	}
	delete[] theterm;
	theterm = newterm;
	delete[] media;
}

int get(int row, int col)
{
	for (int i = 0; i < size; ++i)
	{
		if (theterm[i].rank == row && theterm[i].col == col)
		{
			return theterm;
		}
	}

	return 0;
}

void add(matrix& a, matrix& b, int mine)
{
	if (a.col != b.col || a.rank != b.rank)
	{
		a.col = b.col;
		a.rank = b.rank;
		a.COL = b.COL;
		a.RANK = b.RANK;
		a.size = b.size;
		delete[] a.theterm;
		a.theterm = b.theterm;
		cout << -1 << endl;
	}
	else
	{
		matrix c;
		c.col = b.col;
		c.rank = b.rank;
		c.COL = new int[c.col + 1];
		c.RANK = new int[c.rank + 1];

		for (int i = 1; i < a.rank; ++i)
		{
			for (int j = 1; j < a.col; ++j)
			{
				if (a.get(i, j) + b.get(i, j) != 0)
				{
					c.
				}
			}
		}
	}

}

void add(matrix& a, matrix& b)
{
	if (a.col != b.col || a.rank != b.rank)
	{
		a.col = b.col;
		a.rank = b.rank;
		a.COL = b.COL;
		a.RANK = b.RANK;
		a.size = b.size;
		delete[] a.theterm;
		a.theterm = b.theterm;
		cout << -1 << endl;
	}
	else
	{
		matrix c;
		c.col = b.col;
		c.rank = b.rank;
		c.COL = new int[c.col + 1];
		c.RANK = new int[c.rank + 1];
		for (int i = 1; i <= c.rank; i++)
		{
			c.RANK[i] = 0;
		}
		for (int i = 1; i <= c.col; i++)
		{
			c.COL[i] = 0;
		}
		c.size = b.size;
		c.theterm = new term[c.rank * c.col];
		int i = 0;
		int j = 0;
		int n = 0;
		while (i < a.size && j < b.size)
		{
			if (((a.theterm[i].rank - 1) * a.col + a.theterm[i].col) < ((b.theterm[j].rank - 1) * b.col + b.theterm[j].col))
			{
				c.theterm[n].value = a.theterm[i].value;
				c.theterm[n].rank = a.theterm[i].rank;
				c.theterm[n].col = a.theterm[i].col;
				c.RANK[c.theterm[n].rank]++;
				c.COL[c.theterm[n].col]++;
				i++;
				n++;
			}
			else if (((a.theterm[i].rank - 1) * a.col + a.theterm[i].col) > ((b.theterm[j].rank - 1) * b.col + b.theterm[j].col))
			{
				c.theterm[n].value = b.theterm[j].value;
				c.theterm[n].rank = b.theterm[j].rank;
				c.theterm[n].col = b.theterm[j].col;
				c.RANK[c.theterm[n].rank]++;
				c.COL[c.theterm[n].col]++;
				j++;
				n++;
			}
			else
			{
				c.theterm[n].value = b.theterm[j].value + a.theterm[i].value;
				c.theterm[n].rank = b.theterm[j].rank;
				c.theterm[n].col = b.theterm[j].col;
				c.RANK[c.theterm[n].rank]++;
				c.COL[c.theterm[n].col]++;
				j++;
				i++;
				n++;
			}
		}
		while (i < a.size)
		{
			c.theterm[n].value = a.theterm[i].value;
			c.theterm[n].rank = a.theterm[i].rank;
			c.theterm[n].col = a.theterm[i].col;
			c.RANK[c.theterm[n].rank]++;
			c.COL[c.theterm[n].col]++;
			i++;
			n++;
		}
		while (j < b.size)
		{
			c.theterm[n].value = b.theterm[j].value;
			c.theterm[n].rank = b.theterm[j].rank;
			c.theterm[n].col = b.theterm[j].col;
			c.RANK[c.theterm[n].rank]++;
			c.COL[c.theterm[n].col]++;
			j++;
			n++;
		}
		c.size = n;
		a.COL = c.COL;
		a.RANK = c.RANK;
		a.size = c.size;
		delete[] a.theterm;
		a.theterm = c.theterm;
	}
}

void multi(matrix& a, matrix& b)
{
	if (a.col != b.rank)
	{
		a.col = b.col;
		a.rank = b.rank;
		a.COL = b.COL;
		a.RANK = b.RANK;
		a.size = b.size;
		delete[] a.theterm;
		a.theterm = b.theterm;
		cout << -1 << endl;
	}
	else
	{
		matrix c;
		c.rank = a.rank;
		c.col = b.col;
		c.theterm = new term[a.rank * b.col];
		c.COL = new int[c.col + 1];
		c.RANK = new int[c.rank + 1];
		int* media1 = new int[a.rank + 1];
		media1[1] = 0;
		for (int i = 2; i <= a.col; i++)
		{
			media1[i] = media1[i - 1] + a.RANK[i - 1];
		}
		b.trans();
		int* media2 = new int[b.rank + 1];
		media2[1] = 0;
		for (int i = 2; i <= b.col; i++)
		{
			media2[i] = media2[i - 1] + b.RANK[i - 1];
		}
		for (int i = 1; i <= c.rank; i++)
		{
			c.RANK[i] = 0;
		}
		for (int i = 1; i <= c.col; i++)
		{
			c.COL[i] = 0;
		}
		int n = 0;

		for (int i = 1; i <= a.rank; i++)
		{
			if (a.RANK[i] == 0)
			{
				continue;
			}
			else
			{
				for (int j = 1; j <= b.col; j++)
				{
					if (b.COL[j] == 0)
					{
						continue;
					}
					else
					{
						int sum = 0;
						for (int k = 1; k <= b.rank; k++)
						{
							sum = sum + a.get(i, k) * b.get(k, j);
						}
						c.theterm[n].value = sum;
						c.theterm[n].rank = i;
						c.theterm[n].col = j;
						c.theterm[n].no = (i - 1) * c.col + j;

						c.RANK[i]++;
						c.COL[j]++;
						n++;
					}
				}
			}
		}
		c.size = n;
		a.rank = c.rank;
		a.col = c.col;
		a.COL = c.COL;
		a.RANK = c.RANK;
		a.size = c.size;
		delete[] a.theterm;
		a.theterm = c.theterm;
	}

}







int main()
{
	int n;
	cin >> n;
	matrix a;
	int no;
	for (int i = 0; i < n; i++)
	{
		cin >> no;
		if (no == 1)
			a.input1();
		if (no == 2)
		{
			matrix b;
			b.input2();
			multi(a, b);
		}
		if (no == 3)
		{
			matrix b;
			b.input2();
			add(a, b);
		}
		if (no == 4)
		{
			a.output1();
		}
		if (no == 5)
		{
			a.trans();
		}
	}


}